home *** CD-ROM | disk | FTP | other *** search
/ Aminet 51 / Aminet 51 (2002)(GTI - Schatztruhe)[!][Oct 2002].iso / Aminet / dev / gg / tcpbug.lha / tcpbug / relay1.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-10-02  |  1.6 KB  |  99 lines

  1. #include <errno.h>
  2. #include <string.h>
  3. #include <unistd.h>
  4. #include <sys/time.h>
  5. #include <sys/types.h>
  6. #include <sys/filio.h>
  7. #include <sys/socket.h>
  8.  
  9.  
  10. #define    MAX(a,b)    ((a) > (b) ? (a) : (b))
  11. #define    MIN(a,b)    ((a) < (b) ? (a) : (b))
  12.  
  13.  
  14. int
  15. relay(int fd1,
  16.       int fd2,
  17.       int (*callback)(char prefix, char *data, size_t nbytes))
  18. {
  19.     fd_set readset;
  20.     int nfds, len;
  21.     char buffer[8192];
  22.     int fd1_eof = 0;
  23.     int fd2_eof = 0;
  24.  
  25.     while (!fd1_eof  ||  !fd2_eof)
  26.     {
  27.     /* Setup file descriptor set */
  28.     FD_ZERO(&readset);
  29.     if (!fd1_eof)
  30.         FD_SET(fd1, &readset);
  31.     if (!fd2_eof)
  32.         FD_SET(fd2, &readset);
  33.  
  34.     nfds = select(MAX(fd1, fd2)+1,
  35.               &readset, NULL, NULL, NULL);
  36.  
  37.     /* error? */
  38.     if (nfds < 0)
  39.     {
  40.         if (errno == EINTR)
  41.         continue;
  42.         return -1;
  43.     }
  44.  
  45.     /* timeout? */
  46.     if (nfds == 0)
  47.         continue;
  48.  
  49.     if (FD_ISSET(fd1, &readset))
  50.     {
  51.         long  unread;
  52.         ioctl(fd1, FIONREAD, &unread);
  53.         do
  54.         {
  55.         if ((len = read(fd1, buffer, sizeof buffer)) < 0)
  56.         {
  57.             return -1;
  58.         }
  59.         unread -= len;
  60.  
  61.         /* remote server close? */
  62.         if (len == 0)
  63.         {
  64.             shutdown(fd2, 1);
  65.             fd1_eof = 1;
  66.         }
  67.         callback('>', buffer, len);
  68.         write(fd2, buffer, len);
  69.         } while (unread > 0);
  70.     }
  71.  
  72.     if (FD_ISSET(fd2, &readset))
  73.     {
  74.         long unread;
  75.         ioctl(fd2, FIONREAD, &unread);
  76.         do
  77.         {
  78.         if ((len = read(fd2, buffer, sizeof buffer)) < 0)
  79.         {
  80.             return -1;
  81.         }
  82.         unread -= len;
  83.  
  84.         /* remote client close? */
  85.         if (len == 0)
  86.         {
  87.             shutdown(fd1, 1);
  88.             fd2_eof = 1;
  89.         }
  90.         callback('<', buffer, len);
  91.         write(fd1, buffer, len);
  92.         } while (unread > 0);
  93.     }
  94.  
  95.     }
  96.  
  97.     return 0;
  98. }
  99.